package com.youdianstar.app.ui.account

import androidx.databinding.ObservableField
import androidx.lifecycle.viewModelScope
import com.youdianstar.app.entity.AccountLoginReq
import com.youdianstar.app.entity.MobileLoginResponse
import com.youdianstar.app.entity.UserCenterResponse
import com.youdianstar.app.support.ApiRepository

import com.youdianstar.app.common.COUNTDOWN_TIME
import com.youdianstar.app.common.REQUEST_TIME
import com.youdianstar.app.common.base.BaseViewModel
import com.youdianstar.app.common.entity.BrandEntity
import com.youdianstar.app.common.entity.BrandSwitch
import com.youdianstar.app.common.entity.ConfigItem
import com.youdianstar.app.common.entity.FileUpResult
import com.youdianstar.app.common.entity.UserInfo
import com.youdianstar.app.common.event.NetStateLiveData
import com.youdianstar.app.common.event.SingleLiveEvent
import com.youdianstar.app.common.util.CacheUtil
import com.youdianstar.app.common.util.StrUtil
import com.youdianstar.app.entity.AccountEdit
import com.youdianstar.app.entity.PhoneCurrent

import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import java.util.*


/**
 * File: LoginViewModel
 * Author: 82149 Create: 2021/9/23 11:46
 * Changes (from 2021/9/23)
 * --------------------------------------------------
 * description: 登录页面,兼测试框架功能
 * ---------------------------------------------------
 *
 */
class LoginViewModel(private val repo: ApiRepository) : BaseViewModel() {

    //手机输入数据
    val phoneDataField = ObservableField<String>()
    val emailDataField = ObservableField<String>()
    val otpPhoneField = ObservableField<String>()
    val otpEmailField = ObservableField<String>()
    //TabLayout
    val selectPhoneField = ObservableField<Boolean>(false)

    val phoneCodeCurrentData = NetStateLiveData<PhoneCurrent>()

    /**
     * 获取国家编号
     * ---> IP 默认
     */
    fun getPhoneCodeCurrent() {
        viewModelScope.launch(Dispatchers.IO) {
            repo.getPhoneCodeCurrent(phoneCodeCurrentData)
        }
    }

    val configResultLiveData = NetStateLiveData<List<ConfigItem>>()
    /**
     * 获取系统配置
     */
    fun getSystemConfig(){
        viewModelScope.launch(Dispatchers.IO) {
            repo.getSystemConfig(configResultLiveData)
        }
    }

    //OTP Phone 发送 *************************************************************
    private var countTime = 0L //开始计时时间 (中断/重新开始)
    private var countPhone = 0L
    val phoneCountEvent = SingleLiveEvent<Long>()

    /**初始化otp计时*/
    fun initTimeCount() {
        val time = Date().time
        val oldReqTime: Long = CacheUtil.instance.getLongValue(REQUEST_TIME)
        //总计时时间-(当前时间-上次倒计时时间点)-> distanceTime 剩余倒计时时间 秒
        val offerTime: Long = COUNTDOWN_TIME - (time - oldReqTime) / 1000
        if (offerTime > 0L && CacheUtil.instance.getLongValue(REQUEST_TIME) != 0L) {
            countPhone = offerTime
            return
        }
        countPhone = COUNTDOWN_TIME
    }

    /**调用otp接口成功调用*/
    fun onPhoneOtpSuccess() {
        val time = Date().time
        CacheUtil.instance.setLongValue(REQUEST_TIME, time)
        countPhone = COUNTDOWN_TIME
    }

    /**开始otp到计时*/
    // @ExperimentalCoroutinesApi
    fun downCountPhone() {
        viewModelScope.launch {
            flow {
                (60L downTo 1).forEach {
                    emit(it)
                    delay(1000)
                }
            }.flowOn(Dispatchers.Default)
                .onStart {
                    //enableCountEvent.postValue(true)
                    phoneCountEvent.value = 60L
                }
                .onCompletion {
                    phoneCountEvent.value = -1L
                    countPhone = COUNTDOWN_TIME
                    countTime = COUNTDOWN_TIME
                }
                .collect {
                    phoneCountEvent.value = it
                    countTime = it
                }
        }
    }

    //OTP Email 发送 *************************************************************
    private var countEmail = 0L
    val emailCountEvent = SingleLiveEvent<Long>()

    /**调用otp接口成功调用*/
    fun onEmailOtpSuccess() {
        val time = Date().time
        CacheUtil.instance.setLongValue(REQUEST_TIME, time)
        countEmail = COUNTDOWN_TIME
    }

    /**开始otp到计时*/
    fun downCountEmail() {
        viewModelScope.launch {
            flow {
                (60L downTo 1).forEach {
                    emit(it)
                    delay(1000)
                }
            }.flowOn(Dispatchers.Default)
                .onStart {
                    //enableCountEvent.postValue(true)
                    emailCountEvent.value = 60L
                }
                .onCompletion {
                    emailCountEvent.value = -1L
                    countEmail = COUNTDOWN_TIME
                }
                .collect {
                    emailCountEvent.value = it
                }
        }
    }

    /*****************************************************************************/
    //气泡 显示处理
    val burCountEvent = SingleLiveEvent<Int>()
    private var burCountJob : Job? =null

    fun showAgreeBurLayout(){
        burCountJob = flow{
            for (i in 0..6){
                emit(i)
                delay(1000)
            }
        }.flowOn(Dispatchers.Default)
            .onCompletion {
                //countJob cancel 会走这里
            }
            .onEach {
                burCountEvent.value = it
            }
            .flowOn(Dispatchers.Main)
            .launchIn(viewModelScope)
    }

    fun dismissAgreeBur(){
        burCountJob?.cancel()
        burCountEvent.value = 6
    }


    //登录/OTP 数据回调 : NetStateLiveData
    val otpPhoneResultData = NetStateLiveData<Any>()
    val otpEmailResultData = NetStateLiveData<Any>()

    /**
     * 获取验证码
     * @param countryCode 国家代码，如 "84" (越南)
     * @param phoneNumber 手机号码
     * @param type 验证码类型，登录时使用 'login'
     */
    fun getOTPCode(countryCode: String, phoneNumber: String, type: String = "login") {
        viewModelScope.launch(Dispatchers.IO) {
            repo.getPhoneTOP(countryCode, phoneNumber, type, otpPhoneResultData)
        }
    }

    val loginResultLiveData = NetStateLiveData<MobileLoginResponse>()
    val loginTokenResultLiveData = NetStateLiveData<UserInfo>()

    /**
     * 手机号验证码登录
     *
     * @param countryCode 国家代码，如 "84" (越南)
     * @param phoneNumber 手机号码
     * @param securityCode 验证码
     */
    fun loginAccount(countryCode: String, phoneNumber: String, securityCode: String){
        showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.loginAccount(countryCode, phoneNumber, securityCode, loginResultLiveData)
        }
    }

    /**
     * 账号登录 --token登录
     *
     * @param token 用户token
     */
    fun loginAccountToken(token:String){
        showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.loginAccountToken(token, loginTokenResultLiveData)
        }
    }


    val branchSwitchLiveData = NetStateLiveData<BrandEntity>()
    /**
     * 品牌切换
     * @param req 请求数据
     */
    fun switchBrand(req : BrandSwitch, isShow : Boolean=true){
        if (isShow)
            showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.setBrandSwitch(req,branchSwitchLiveData)
        }
    }

    /**************************************个人中心***************************************/
    val fileUploadLiveData = NetStateLiveData<FileUpResult>()

    /**
     * 头像上传
     * @param path 文件路径
     */
    fun upLoadImage(path: String){
        showLoading()
        viewModelScope.launch {
            repo.upLoadImage(path,fileUploadLiveData)
        }
    }

    val userResultLiveData = NetStateLiveData<UserInfo>()
    val userCenterResultLiveData = NetStateLiveData<UserCenterResponse>() // 新增：用于获取用户中心完整数据
    val editResultLiveData = NetStateLiveData<Any>()

    //OTP 数据回调 : NetStateLiveData
    val otpResultLiveData = NetStateLiveData<Any>()
    val timeCountEvent = SingleLiveEvent<Long>()
    private var countOtpTime = 0L
    private var otpCount = 0L

    /**获取用户信息*/
    fun getAccount(){
        //showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.getUserCenter(userCenterResultLiveData)
        }
    }

    /**
     * 编辑用户信息
     *
     * @param req request
     */
    fun edtAccount(req: AccountEdit){
        showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.editAccount(req,editResultLiveData)
        }
    }

    val editNicknameLiveData = NetStateLiveData<Any>()

    /**
     * 修改昵称
     */
    fun editNickname(userId: Int, nickname: String) {
        showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.editNickname(userId, nickname, editNicknameLiveData)
        }
    }

    /**
     * 获取编辑手机号验证码
     * @param code 国家代码
     * @param phone 手机号
     * @param email 邮箱
     */
    fun getEditPhoneOTP(code: String?, phone: String?,email: String?) {
        viewModelScope.launch(Dispatchers.IO) {
            if (!StrUtil.isEmpty(phone)) {
                // 手机号验证码
                repo.getPhoneTOP(code ?: "1", phone ?: "", "binding", otpResultLiveData)
            } else if (!StrUtil.isEmpty(email)) {
                // TODO: 邮箱验证码功能需要新的API接口支持
                // repo.getPhoneTOP("", email ?: "", "email", otpResultLiveData)
            }
        }
    }


    /**
     * 调用otp接口成功调用
     */
    fun onOtpSuccess() {
        val time = Date().time
        CacheUtil.instance.setLongValue(REQUEST_TIME, time)
        otpCount = COUNTDOWN_TIME
    }

    /**
     * 开始otp到计时
     */
    fun downCount() {
        viewModelScope.launch {
            flow {
                (60L downTo 1).forEach {
                    emit(it)
                    delay(1000)
                }
            }.flowOn(Dispatchers.Default)
                .onStart {
                    //enableCountEvent.postValue(true)
                    timeCountEvent.value = 60L
                }
                .onCompletion {
                    timeCountEvent.value = -1L
                    otpCount = COUNTDOWN_TIME
                    countOtpTime = COUNTDOWN_TIME
                }
                .collect {
                    timeCountEvent.value = it
                    countOtpTime = it
                }
        }
    }

    /**************************************账号修改***************************************/

    val verifyResultLiveData = NetStateLiveData<Any>()

    /**
     * 校验原账号
     *
     * @param code 国家/地区码
     * @param phone 手机号
     * @param email 邮箱地址
     * @param msgCode 短信验证码
     */
    fun verifyAccount(code: String?, phone: String?, email: String?, msgCode: String){
        showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.verifyAccount(code,phone,email,msgCode,verifyResultLiveData)
        }
    }

    val cancelResultLiveData = NetStateLiveData<Any>()
    /**
     * 清除用户信息
     */
    fun cancelUserAccount(){
        showLoading()
        viewModelScope.launch(Dispatchers.IO) {
            repo.userAccountCancel(cancelResultLiveData)
        }
    }
}